﻿using System;
using System.Linq.Expressions;
using System.Reflection;

namespace RuntimeHelloWorlds
{
	/// <summary>
	/// The fantastic System.Linq.Expressions namespace provides a way to 
	/// write code using the Expression object model, then compile it 
	/// easily to a delegate.
	/// 
	/// The key here is that you use the Expression class' static 
	/// factory methods to create any specific subclass of epxression
	/// you want.
	/// </summary>
	public class ExpressionHelloWorld
	{
		public void SayHelloWorld()
		{
			// The below assignment of methodInfo is a 'cute' shortcut method to
			// use a delegate to get a particular overload faster then the normal method:
			// MethodInfo methodInfo = typeof(Console).GetMethod("WriteLine", new[] { typeof(string) });
			// it's *not much* faster, but slightly less code and so I think worth it, YMMV.
			MethodInfo methodInfo = new Action<string>(Console.WriteLine).Method;

			MethodCallExpression helloWorldBody
				= Expression.Call(methodInfo,
					Expression.Constant("Hello, World! (Expression Tree)"));

			Expression<Action> helloWorldMethod
				= Expression.Lambda<Action>(helloWorldBody);

			Action helloWorldDelegate = helloWorldMethod.Compile();
			helloWorldDelegate();
		}
	}
}
